﻿using System;
using System.Linq;
using SvnDeploy.Service.Cfg;

namespace SvnDeploy.Service.Impl
{
    internal class BackupProviderImpl : IBackupProvider
    {
        private readonly IFileSystem fileSystem;
        private readonly IZipAdapter zipAdapter;

        public BackupProviderImpl(IFileSystem fileSystem, IZipAdapter zipAdapter, SvnDeployConfigurationSection config)
        {
            this.fileSystem = fileSystem;
            this.zipAdapter = zipAdapter;
            SetValuesFromConfiguration(config);
        }
       
        public string BackupPath { get; private set; }

        public int NumberOfBackupsToKeep { get; private set; }

        public bool ShouldBackup { get; private set; }

        public void Backup(string name, string folderToBackup)
        {
            if (!ShouldBackup) return; // No reason to continue if backups are turned off.            
            VerifyBackupDirectoryExists();
            var zipPath = BuildZipPath(name);
            zipAdapter.ZipFolder(folderToBackup, zipPath);
            DeleteOldBackups(name);
        }

        private string BuildZipPath(string name)
        {
            var timeStamp = DateTime.Now.ToString("u").Replace(":", "");
            return BackupPath + @"\" + name + " (" + timeStamp + ").zip";
        }

        private void DeleteOldBackups(string name)
        {
            fileSystem.GetFiles(BackupPath)
                .Where(f => f.Name.StartsWith(name) && f.Name.EndsWith(".zip"))
                .OrderByDescending(f => f.LastWriteTime)
                .Skip(NumberOfBackupsToKeep)
                .ForEach(f => fileSystem.DeleteFile(f.FullName));            
        }

        private void SetValuesFromConfiguration(SvnDeployConfigurationSection config)
        {
            BackupPath = config.BackupSettings.Path;
            NumberOfBackupsToKeep = config.BackupSettings.NumberOfBackupsToKeep;
            ShouldBackup = config.BackupSettings.Backup;
        }

        private void VerifyBackupDirectoryExists()
        {
            if (!fileSystem.DoesDirectoryExist(BackupPath))
            {
                fileSystem.CreateDirectory(BackupPath);
            }
        }
    }
}
